home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / swaga_c.zip / ARCHIVES.SWG / 0027_Full Zip File Functions.pas < prev    next >
Pascal/Delphi Source File  |  1995-03-03  |  11KB  |  287 lines

  1. {
  2. The following code is a cheezy way to read the structures that exist in a
  3. zip file. it does not compress or decompress; it just reads the file
  4. information included in the file. It is not finished and has a bug that has
  5. been compensated for.
  6. Enjoy -some code is not my own, i.e. the structures themselves.
  7. }
  8.  
  9. USES dos;   {Structure signatures}
  10. CONST  LOCAL   = $04034B50; CENTRAL = $02014B50;END_OF  = $06054B50;
  11. {THE following three structures are found in the zip file }
  12. {A signature WILL tell you WHICH follows the signature in the file}
  13. TYPE ZLOCALtype  = record      { Zip File Header          }
  14. VerReqd        : Word;                       { ..Version reqd to unzip  }
  15. BitFlag        : Word;                       { ..Bit Flag                  }
  16. Method        : Word;                       { ..Compress Method          }
  17. LModTime: Word;                       { ..Last Mod Time          }
  18. LModDate: Word;                       { ..Last Mod Date          }
  19. CRC32        : LongInt;               { ..File CRC                  }
  20. CmpSize : LongInt;               { ..Compressed Size          }
  21. UncmpSz        : LongInt;               { ..Uncompressed Size          }
  22. FNLen        : Word;                       { ..File Name Length          }
  23. EFLen        : Word;                       { ..Extra Field Length          }
  24. end;
  25.  
  26. TYPE ZCENTRALtype  = record     { Zip File Header            }
  27. MadeBy  : Word;
  28. VerReqd        : Word;                        { ..Version reqd to unzip   }
  29. BitFlag        : Word;                        { ..Bit Flag                   
  30.  }
  31. Method        : Word;                        { ..Compress Method           
  32. }
  33. LModTime: Word;                        { ..Last Mod Time            }
  34. LModDate: Word;                        { ..Last Mod Date            }
  35. CRC32        : LongInt;                { ..File CRC                    }
  36. CmpSize : LongInt;                { ..Compressed Size            }
  37. UncmpSz        : LongInt;                { ..Uncompressed Size            }
  38. FNLen        : Word;                        { ..File Name Length           
  39. }
  40. EFLen        : Word;                        { ..Extra Field Length           
  41.  }
  42. end;
  43. zCENTRAL2type=record
  44. DiskNo        : Word;                        { ..Starting Disk Number    }
  45. IFAttr        : Word;                        { ..Internal File Attributes}
  46. EFAttr        : LongInt;                { ..External File Attributes}
  47. LHOff        : LongInt;                { ..Offset of local header  }
  48. end;
  49.  
  50. zENDType = Record               { Directory End Record            }
  51. DiskNo        : Word;                        { ..Number of this disk         
  52.    }
  53. ZDDisk        : Word;                        { ..Disk w/ start of dir    }
  54. ZDETD        : Word;                        { ..Dir ents this disk           
  55.  }
  56. ZDEnts        : Word;                        { ..Total dir ents            }
  57. ZDSize        : LongInt;                { ..Dir size                    }
  58. ZDStart        : LongInt;                { ..Offset to start of Dir  }
  59. CmtLen        : Word;                        { ..Zip Comment Length          
  60.   }
  61. end;
  62.  
  63. VAR zLOCAL   : zLOCALtype;
  64.     zCENTRAL : zCENTRALtype;
  65.     zCENTRAL2: zCENTRAL2type;
  66.     zEND     : zENDtype;
  67.     Fi : File;
  68.     FIlename:String[12];
  69.     temp : array[1..16] of char;
  70.     zSignature: longInt;
  71.     I : integer;
  72. {$I files.inc}   {for opening files easy}
  73. {$I buffer.inc}  {Using a full buffer and fake disk reads}
  74.                  {Nice when you don't know what structure follows}
  75.                  {Fill the buffer and move the info to the structure
  76.                   that fits}
  77. Function num2Hex(L : LongInt) : String;
  78. CONST   HexChar  : Array [0..15] of Char = '0123456789ABCDEF';
  79. VAR   hexs       : string;
  80.       tByte, I,J : byte;
  81.       start      : boolean;
  82. Begin
  83.    HexS:='';
  84.    HexS     := HexChar[(L AND $F0000000) SHR 28] +
  85.                HexChar[(L AND $0F000000) SHR 24] +
  86.                HexChar[(L AND $00F00000) SHR 20] +
  87.                HexChar[(L AND $000F0000) SHR 16] +
  88.                HexChar[(L AND $0000F000) SHR 12] +
  89.                HexChar[(L AND $00000F00) SHR  8] +
  90.                HexChar[(L AND $000000F0) SHR  4] +
  91.                HexChar[(L AND $0000000F)       ];
  92.  Start:=False;                 {init}
  93.  j:=0;
  94.   FOR I:=1 to 8 DO BEGIN        {rid of leading zeros}
  95.     IF hexS[i]<>'0' then Start:=true;
  96.     IF start then BEGIN
  97.        Inc(j,1);
  98.        HexS[j]:=HexS[i];
  99.     END;
  100.   END;
  101.   move(j,hexS[0],1);            {reset string to new size}
  102.   num2Hex:=HexS;
  103. end; {HexLInt}
  104. BEGIN {-==<SKELETON>==-}
  105.   {Open the file if it exists; else OpenFile returns FALSE}
  106.   IF not OpenFile(fi, paramStr(1)) then BEGIN
  107.     Writeln('File ', paramStr(1) ,' not found. Check syntax');
  108.     halt;
  109.   END;
  110.   BRead(Fi, Zsignature, 4); {Fills the buffer}
  111.                             {Moves 4 bytes into zSignature}
  112.   IF (Zsignature<>LOCAL) and (zSignature<>CENTRAL) THEN BEGIN
  113.      Writeln('File ',ParamStr(1),' does not appear to be a ZIP file.');
  114.      HALT
  115.   END;
  116.   WHILE 1<>0  DO BEGIN
  117.   {Read the structure that fits the zSignature}
  118.    IF zSignature=  LOCAL   THEN BEGIN
  119.       Bread(fi,Zlocal,SizeOf(Zlocal) );
  120.       Writeln('LOCAL');
  121.    END;
  122.    IF zSignature=  CENTRAL THEN BEGIN
  123.       Bread(fi,ZCentral,SizeOf(Zlocal) );
  124.       WriteLN('CENTRAL');
  125.    END;
  126.    IF zSignature=  END_OF  THEN BEGIN
  127.       Bread(fi,zEnd,SizeOf(zEnd) );
  128.       WriteLN('END');
  129.    END;
  130.    {ALL three have a signature}
  131.   { Writeln('long test ',num2hex(981347578));}
  132.    Write('Pksignature:        ');
  133.    write(      ((Zsignature and $F0000000) shr 28) );
  134.    write(' ',  ((Zsignature and $0F000000) shr 24) );
  135.    write(' ',  ((Zsignature and $00F00000) shr 20) );
  136.    write(' ',  ((Zsignature and $000F0000) shr 16) );
  137.    write(' ',  ((Zsignature and $0000F000) shr 12) );
  138.    write(' ',  ((Zsignature and $00000F00) shr 8) );
  139.    write(' ',  ((Zsignature and $000000F0) shr 4) );
  140.    write(' ',  ((Zsignature and $0000000F) ) );
  141.    writeln;
  142.    IF (zSignature=Local) THEN BEGIN
  143.      WITH zLOCAL DO BEGIN
  144.       Write('Version Required:   ',(verReqd div 10),'.' );
  145.       writeln(VerReqd mod 10);
  146.       writelN('BitFlag [?]:        ',(bitflag) );
  147.       WriteLN('Method Used:        ',(method)  );
  148.       WriteLN('Last mod Time:      ',num2hex(LmodTime));
  149.       WriteLN('Last mod Date:      ',num2hex(LmodDate));
  150.       WriteLN('CRC32:              ',num2hex(Crc32)); {Correct}
  151.       Writeln('Compressed Size:    ',CmpSize);  {correct}
  152.       WriteLn('Original Size:      ',UnCmpSz);  {correct}
  153.       Writeln('File name Length:   ',FNlen);    {correct}
  154.       Writeln('Extra field Length: ',EFlen);
  155.       BRead(Fi,Filename[1],FNlen);
  156.       move (FNlen,FileName[0],1);     {init the string length}
  157.       WriteLN('FileName:           ',FileName); {correct}
  158.       Bskip(fi,CmpSize);                    {skip the actual zipped part}
  159.      END;
  160.    END;
  161.    IF (zSignature=CENTRAL) THEN BEGIN
  162.      WITH zCENTRAL DO BEGIN
  163.       Writeln('MAde by version :   ',madeBy);
  164.       Write('Version Required:   ',(verReqd div 10),'.' );
  165.       writeln(VerReqd mod 10);
  166.       writelN('BitFlag [?]:        ',(bitflag) );
  167.       WriteLN('Method Used:        ',(method)  );
  168.       WriteLN('Last mod Time:      ',num2hex(LmodTime));
  169.       WriteLN('Last mod Date:      ',num2hex(LmodDate));
  170.       WriteLN('CRC32:              ',num2hex(Crc32));
  171.       Writeln('Compressed Size:    ',CmpSize);
  172.       WriteLn('Original Size:      ',UnCmpSz);
  173.       Writeln('File name Length:   ',FNlen);
  174.       Writeln('Extra field Length: ',EFlen);
  175.      END;
  176.      WITH zCENTRAL2 DO BEGIN
  177.       BSkip(fi,4); {There's blanks?? why?}
  178.       Bread(Fi,zCentral2,SizeOf(zCentral2));
  179.        Writeln('Starting Disk #:      ',DiskNo);
  180.        WriteLN('Internal File Attr:   ',IFAttr);
  181.        WriteLN('External File Attr:   ',EFAttr);
  182.        Writeln('Local header offset:  ',LHoff);
  183.       BRead(Fi,Filename[1],zCENTRAL.FNlen);
  184.       move (zCENTRAL.FNlen,FileName[0],1);
  185.        WriteLN('FileName:           ',FileName);
  186.      END;
  187.    END;
  188.    IF (zSignature=END_OF) THEN BEGIN
  189.      WITH zEND DO BEGIN
  190.        WriteLN('Disk Number:         ',DiskNo);
  191.        WriteLN('Start of directory:  ',ZDDisk);
  192.        WriteLN('Total entries, disk: ',ZDETD);
  193.        WriteLN('Total Entries:       ',ZDEnts);
  194.        WriteLN('Directory Size:      ',ZDSize);
  195.        WriteLN('Directory Offset:    ',ZDStart);
  196.        WriteLN('Zip Comment Length:  ',CmtLen);
  197.        halt;
  198.      END;
  199.    END;
  200.    ReadLN;
  201.    Bread(fi,zSignature,4);               {read next Zsignature}
  202.   END; {WHILE NOT EOF}
  203.   Close(fi);
  204. END.
  205.  
  206. { FILES.INC}
  207. FUNCTION FileExists(FileName: String): Boolean;
  208. VAR   F: file;
  209. begin
  210.   {$I-}
  211.   Assign(F, FileName);
  212.   Reset(F);
  213.   Close(F);
  214.   {$I+}
  215.   FileExists:=(IOResult = 0) and (FileName <> '')
  216.  end;  { FileExists }
  217. FUNCTION OpenFile(VAR f: file; fileName:string): Boolean;
  218. BEGIN
  219.    IF fileExists(FileName) then BEGIN
  220.       Assign(f,filename);
  221.       Reset(f,1);
  222.       Openfile:=True;
  223.    END
  224.    ELSE OpenFile:=False;
  225. END;
  226.  
  227. FUNCTION FileExistsWild(FileName: String): Boolean;
  228. VAR   Fil: SearchRec;
  229. begin
  230.   FindFirst(FileName,anyFile,Fil);
  231.   FileExistsWild:=(DosError=0) and (FileName <> '');
  232. end;  { FileExists }
  233.  
  234.  
  235. {BUFFER.INC}
  236. CONST zBufSize=8192;
  237. TYPE zBufferType = array[1..zBufSize] of byte;
  238. VAR zBuffer: zBufferType;
  239.     zCurrent: integer;
  240.     nSeen : Word;
  241. PROCEDURE READBUFFER(Var f:file;nRead, Position: integer);
  242. BEGIN
  243.  IF zCurrent=0 then zCurrent:=1;
  244.  BlockRead(f,zBuffer[Position],nRead,nSeen);
  245. END;
  246.  
  247. PROCEDURe bREAD(var f: file;var userObj; nRead: integer);
  248. VAR temp:integer;          {^^^^^^^^^^^what ever the user is using!}
  249. BEGIN
  250.  IF zCurrent=0 then ReadBUFFER(F, ZBufsize ,1);  {init the buffer}
  251.  IF zcurrent+nRead>zBufSize THEN BEGIN         {Part Missing??}
  252.     Temp:=ZbufSize+1-zCurrent;                   {Size of whats left in
  253. buffer}
  254.    { Writeln('What is left in the buffer ',temp);}
  255.     move(zBuffer[zCurrent], zBuffer[1], Temp); {move unread to start}
  256.     ReadBUFFER(F, ZBufsize-(Temp) ,Temp);     {total minus what's left}
  257.     zCurrent:=1;                              {at position end of temp}
  258.     move(zBuffer[zCurrent],userOBJ,nREAD);
  259.  END
  260.  else BEGIN
  261.  move(ZBuffer[zCurrent],UserOBJ,nREad);
  262.  zCurrent:=zCurrent+nRead;
  263.  END;
  264. END;
  265.  
  266. PROCEDURe bSkip(var f: file; nRead: integer);
  267. VAR temp:integer;  {SKIPS A PART OF THE BUFFER}
  268. BEGIN
  269.  IF zCurrent=0 then ReadBUFFER(F, ZBufsize ,1);  {init the buffer}
  270.  IF nRead>zBufSize then BEGIN
  271.     Seek(f,FilePos(f)+nRead-(ZbufSize+1-zCurrent));
  272.     {Remeber there may still be bytes ALREADY read in the buffer}
  273.     {You need not skip what's already there}
  274.     {Just seek to position - already read}
  275.     zCurrent:=0;
  276.  END
  277.  ELSE
  278.  IF zcurrent+nRead>zBufSize THEN BEGIN         {Part Missing??}
  279.     Temp:=ZbufSize+1-zCurrent;                 {Size of whats left in
  280. buffer}
  281.     move(zBuffer[zCurrent], zBuffer[1], Temp);    {move unread to start}
  282.     ReadBUFFER(F, ZBufsize-(Temp) ,Temp);{refill} {total minus what's left}
  283.     zCurrent:=1+temp;                             {at position end of temp}
  284.  END
  285.  ELSE zCurrent:=zCurrent+nRead;
  286. END;
  287.